using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

using Alone;
using Alone.Handlers;

namespace NetworkStateManagement.Handlers
{
	public interface IHUDHandler { }

	public struct HUDCounter
	{
		public Texture2D icon;
		public string text;
		public Rectangle iconTarget;
		public Vector2 textTarget;

		public HUDCounter(Texture2D icon, string text, Rectangle target)
		{
			this.icon = icon;
			this.text = text;
			this.iconTarget = new Rectangle(target.X, target.Y, target.Height, target.Height);
			this.textTarget = new Vector2(target.X + iconTarget.Width, target.Y);
		}

		public void Draw(SpriteBatch batch, SpriteFont font)
		{
			batch.Draw(icon, iconTarget, Color.White);
			batch.DrawString(font, text, textTarget, Color.White);
		}
	}
	
	/// <summary>
	/// This is a game component that implements IUpdateable.
	/// </summary>
	public class HUDHandler : Microsoft.Xna.Framework.DrawableGameComponent, IHUDHandler
	{
		private IScreenManager screenManager;
		private IPlayerHandler playerHandler;

		private SpriteFont spriteFont;

		//private List<HUDCounter> counters = new List<HUDCounter>(3);

		private int counterWidth, counterHeight;
		private HUDCounter healthCounter;
		private HUDCounter jetCounter;

		public HUDHandler(Game game)
			: base(game)
		{
			game.Services.AddService(typeof(IHUDHandler), this);
		}

		/// <summary>
		/// Allows the game component to perform any initialization it needs to before starting
		/// to run.  This is where it can query for any required services and load content.
		/// </summary>
		public override void Initialize()
		{
			screenManager = (IScreenManager)Game.Services.GetService(typeof(IScreenManager));
			playerHandler = (IPlayerHandler)Game.Services.GetService(typeof(IPlayerHandler));
			
			// The HUD counters can take up to 25% of the screen in both height and width.
			// And there are 3 counters stacked -- health, jet, and ammo.
			counterHeight = (int)Math.Ceiling((Game.GraphicsDevice.DisplayMode.Height * 0.25f) / 3f);
			counterWidth = (int)Math.Ceiling(Game.GraphicsDevice.DisplayMode.Width * 0.25f);

			base.Initialize();
		}

		protected override void LoadContent()
		{
			Rectangle healthDestination;
			Rectangle jetDestination;
			Rectangle safe = Game.GraphicsDevice.DisplayMode.TitleSafeArea;

			healthDestination.Width = jetDestination.Width = counterWidth;
			healthDestination.Height = jetDestination.Height = counterHeight;

			healthDestination.X = jetDestination.X = safe.Left;

			healthDestination.Y = safe.Bottom - counterHeight;
			jetDestination.Y = healthDestination.Y - counterHeight;	
			
			spriteFont = Game.Content.Load<SpriteFont>("gamefont");
			
			healthCounter = new HUDCounter(
				(Texture2D)Game.Content.Load<Texture2D>("Health"),
				Convert.ToString(playerHandler.Player.Hp),
				healthDestination
			);
			jetCounter = new HUDCounter(
				(Texture2D)Game.Content.Load<Texture2D>("jetpack"),
				Convert.ToString(playerHandler.Player.Jetpack),
				jetDestination
			);

			base.LoadContent();
		}
		
		/// <summary>
		/// Allows the game component to update itself.
		/// </summary>
		/// <param name="gameTime">Provides a snapshot of timing values.</param>
		public override void Update(GameTime gameTime)
		{
			healthCounter.text = Convert.ToString(playerHandler.Player.Hp);
			jetCounter.text = Convert.ToString(playerHandler.Player.Jetpack);

			base.Update(gameTime);
		}

		public override void Draw(GameTime gameTime)
		{
			SpriteBatch batch = screenManager.SpriteBatch;
			
			batch.Begin();

			healthCounter.Draw(batch, spriteFont);
			jetCounter.Draw(batch, spriteFont);

			batch.End();
			
			base.Draw(gameTime);
		}
	}
}